import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import '../../base/base_chart.dart';
import 'base_pie_entity.dart';

/// 饼状图基类
///
/// [D]为饼状图数据，[C]为饼状图子类，[G]为饼状图手势处理，[S]为饼状图[State]
abstract class BasePieChart<
    D,
    C extends BasePieChart<D, C, G, S>,
    G extends BasePieChartGestureHandler<D, G, C, S>,
    S extends BasePieChartState<D, C, G, S>> extends BaseChart<D, G> {
  BasePieChart(
      {super.key,
      super.animDuration,
      required this.radius,
      super.gestureHandler,
      super.painterBuilder,
      super.data,
      this.innerRadius = 0,
      this.sliceSpace = 0,
      this.baseMapColor = Colors.transparent,
      this.drawStartAngle = 0,
      super.emptyWidgetBuilder,
      LabelPosition? labelPosition})
      : assert(radius > 0),
        assert(innerRadius >= 0),
        assert(radius > innerRadius, "radius must than more innerRadius") {
    this.labelPosition = labelPosition ?? LabelPosition.inside();
  }

  /// 饼状图半径
  final double radius;

  /// 内圆半径，== 0则绘制扇形，> 0则绘制圆环
  final double innerRadius;

  /// 每个扇形之间的间距
  final double sliceSpace;

  /// 底图颜色，未设置任何饼状图数据时绘制的底图
  final Color baseMapColor;

  /// 起始绘制的角度
  final double drawStartAngle;

  /// 标签绘制位置
  late final LabelPosition labelPosition;
}

/// 饼状图[State]基类
///
/// [D]为饼状图数据，[C]为饼状图子类，[G]为饼状图手势处理，[S]为饼状图[State]
abstract class BasePieChartState<
    D,
    C extends BasePieChart<D, C, G, S>,
    G extends BasePieChartGestureHandler<D, G, C, S>,
    S extends BasePieChartState<D, C, G, S>> extends BaseChartState<D, G, C> {
  BoxConstraints? _constraints;

  @override
  Widget buildChild(
      BuildContext context, double animProgress, BoxConstraints constraints) {
    _constraints = constraints;
    return super.buildChild(context, animProgress, constraints);
  }

  Offset getCenter() {
    var box = _constraints;
    return box == null
        ? Offset.zero
        : Offset(box.maxWidth / 2, box.maxHeight / 2);
  }
}

/// 饼状图基本绘制器
///
/// [D]为饼状图数据，[C]为饼状图子类，[G]为饼状图手势处理，[S]为饼状图[State]
abstract class BasePieChartPainter<
    D,
    G extends BasePieChartGestureHandler<D, G, C, S>,
    C extends BasePieChart<D, C, G, S>,
    S extends BasePieChartState<D, C, G, S>> extends CustomPainter {
  BasePieChartPainter({required this.state, this.animProgress = 1})
      : assert(animProgress >= 0 && animProgress <= 1);

  /// 绘制器所依赖的饼状图[KqBasePieChartState]
  final S state;

  /// 动画进度，用于根据动画进行进行绘制
  final double animProgress;

  @override
  void paint(Canvas canvas, Size size) {
    if(size.isEmpty) {
      return;
    }

    drawBg(canvas, size);
    if (state.widget.isEmptyData()) {
      return;
    }

    drawData(canvas, size);
    drawLabel(canvas, size);
  }

  /// 绘制饼状图
  @protected
  void drawData(Canvas canvas, Size size);

  /// 绘制饼状图标签
  @protected
  void drawLabel(Canvas canvas, Size size);

  /// 绘制饼状图背景
  @protected
  void drawBg(Canvas canvas, Size size);

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    var result = oldDelegate is! BasePieChartPainter ||
        oldDelegate.state != state ||
        oldDelegate.state.widget != state.widget ||
        oldDelegate.state.widget is! BasePieChart;
    if (result) {
      return true;
    }

    BasePieChart chart = oldDelegate.state.widget;
    return chart.data != state.widget.data ||
        chart.radius != state.widget.radius ||
        chart.innerRadius != state.widget.innerRadius ||
        chart.sliceSpace != state.widget.sliceSpace ||
        chart.baseMapColor != state.widget.baseMapColor ||
        chart.drawStartAngle != state.widget.drawStartAngle ||
        chart.labelPosition != state.widget.labelPosition ||
        chart.animDuration != state.widget.animDuration ||
        oldDelegate.animProgress != animProgress ||
        chart.gestureHandler != state.widget.gestureHandler;
  }
}

/// 饼状图手势处理基类
///
/// [D]为饼状图数据，[C]为饼状图子类，[G]为饼状图手势处理，[S]为饼状图[State]
abstract class BasePieChartGestureHandler<
    D,
    G extends BasePieChartGestureHandler<D, G, C, S>,
    C extends BasePieChart<D, C, G, S>,
    S extends BasePieChartState<D, C, G, S>> with BaseChartGestureHandler {
  /// 当[KqBasePieChartState] initState时调用
  void attachChart(S state);

  /// 当[KqBasePieChartState] dispose时调用
  void dispose();

  @override
  void onDragDown(DragDownDetails details) {}

  @override
  void onDragUpdate(DragUpdateDetails details) {}

  @override
  void onDragEnd(DragEndDetails details) {}

  @override
  void onDragCancel() {}
}
